package com.baizhi.serviceimpl;

import com.baizhi.annotation.AddCache;
import com.baizhi.annotation.AddLog;
import com.baizhi.dao.LikeMapper;
import com.baizhi.dao.UserMapper;
import com.baizhi.dao.VideoMapper;
import com.baizhi.entity.*;
import com.baizhi.po.VideoPO;
import com.baizhi.repository.VideoRepository;
import com.baizhi.service.UserService;
import com.baizhi.service.VideoService;
import com.baizhi.util.ALiyunOSSUtil;
import com.baizhi.util.UUIDUtil;
import com.baizhi.vo.CommonQueryPageVO;
import org.apache.ibatis.session.RowBounds;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;

@Service
@Transactional
public class VideoServiceImpl implements VideoService {

    private static final Logger log = LoggerFactory.getLogger(VideoServiceImpl.class);
    @Resource
    VideoMapper videoMapper;
    @Resource
    LikeMapper likeMapper;

    @Resource
    RestHighLevelClient restHighLevelClient;

    @Resource
    VideoRepository videoRepository;

    @Override
    public HashMap<String, Object> update(Video video) {
        HashMap<String, Object> map = new HashMap<>();
        try {
            videoMapper.updateByPrimaryKeySelective(video);
            map.put("message","修改成功!!!!");
        } catch (Exception e) {
            e.printStackTrace();
            map.put("message","修改失败!!!!");
        }
        return map;
    }

    @AddCache
    @Override
    public CommonQueryPageVO queryAllPages(Integer page, Integer pageSize) {

        //设置查询条件对象
        VideoExample example = new VideoExample();

        //查询总条数
        int total = videoMapper.selectCountByExample(example);

        //创建分页对象  参数：起始条数,数据数
        RowBounds rowBounds = new RowBounds((page-1)*pageSize,pageSize);

        //根据分页查询数据
        List<Video> videos = videoMapper.selectByExampleAndRowBounds(example, rowBounds);

        return new CommonQueryPageVO(page,total,videos);
    }

    @Override
    public void updates(Video video) {

        videoMapper.updateByPrimaryKeySelective(video);

        //根据id将修改后的视频数据查询出来

        //修改索引
        videoRepository.save(video);
    }

    @Override
    public void add(Video video) {

        video.setId(UUID.randomUUID().toString());
        video.setStatus("1");
        video.setCreateTime(new Date());
        video.setUserId("4");

        log.info("添加视频add:{}",video);

        //添加数据
        videoMapper.insertSelective(video);

        //添加索引
        videoRepository.save(video);
    }

    @Override
    public HashMap<String, String> uploadHeadImg(MultipartFile videoFile) {
        //1.获取文件名
        String filename = videoFile.getOriginalFilename();
        log.info("文件名:{}",videoFile.getOriginalFilename());
        log.info("文件大小:{}",videoFile.getSize());
        log.info("文件类型:{}",videoFile.getContentType());
        //添加唯一标识
        String newName = new Date().getTime()+"-"+filename;
        String objectName = "video/"+newName;




        ALiyunOSSUtil.uploadfileBytes("yingx-2111",objectName,videoFile);

        URL url = ALiyunOSSUtil.videoInterceptCover("yingx-2111", objectName);
        System.out.println(url);
        //通过视频名获取图片名
        String coverName = "videoCover/"+newName.split("\\.")[0]+".jpg";

        //将视频封面上传到阿里云
        try {
            ALiyunOSSUtil.uploadNetIo("yingx-2111",coverName,url.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }



        /*try {
            ALiyunOSSUtil.videoInterceptCoverupload("yingx-2111",objectName,coverName);
        } catch (IOException e) {
            e.printStackTrace();
        }*/

        String netPath="https://yingx-2111.oss-cn-beijing.aliyuncs.com/"+objectName;
        String coverNames="https://yingx-2111.oss-cn-beijing.aliyuncs.com/"+coverName;
        HashMap<String, String> map = new HashMap<>();
        map.put("fileName",netPath);
        map.put("coverName",coverNames);

        return map;
    }

    @Override
    public void delete(Video video) {
        Video videos = videoMapper.selectOne(video);
        System.out.println(videos);

        String videoPath = videos.getVideoPath();
        String coverPaths = videos.getCoverPath();

        String replace = videoPath.replace("https://yingx-2111.oss-cn-beijing.aliyuncs.com/", "");
        String replaces = coverPaths.replace("https://yingx-2111.oss-cn-beijing.aliyuncs.com/", "");

        ALiyunOSSUtil.deleteFile("yingx-2111",replace);
        ALiyunOSSUtil.deleteFile("yingx-2111",replaces);

        videoMapper.delete(video);

        //3.删除索引
        videoRepository.delete(video);
    }

    @AddCache
    @Override
    public Video queryById(String id) {
        return videoMapper.selectByPrimaryKey(id);
    }

    @Override
    public List<VideoPO> queryByReleaseTime() {
        //获取数据
        List<VideoPO> pos = videoMapper.queryByReleaseTime();
        //遍历视频数据
        for (VideoPO po : pos) {
            //获取视频ID
            String videoId = po.getId();
            LikeExample example = new LikeExample();
            //根据视频ID查询视频的点赞数
            example.createCriteria().andVideoIdEqualTo(videoId);
            Integer count = likeMapper.selectCountByExample(example);

            po.setLikeCount(count);
        }

        return pos;
    }

    @Override
    public List<Video> searchVideo(String content) throws IOException {

        //创建处理高亮的对象
        HighlightBuilder highlightBuilder = new HighlightBuilder()
                .preTags("<span style='color:red'>")  //高亮前缀
                .postTags("</span>") //高亮的后缀
                .requireFieldMatch(false) //开启多行高亮
                .field("*");

        //创建搜索条件对象
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder()
                .query(QueryBuilders
                        .queryStringQuery(content)  //搜索条件
                        .field("title")  //匹配的字段
                        .field("description")   //匹配的字段
                        .analyzer("ik_max_word"))  //指定搜索的分词器
                .highlighter(highlightBuilder);    //设置高亮查询

        //创建搜索请求对象
        SearchRequest searchRequest = new SearchRequest()
                .indices("yingx")  //设置索引
                .types("video")  //设置类型
                .source(searchSourceBuilder);  //设置搜索条件 搜索的方式

        //搜索索引
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        /**--------------------数据处理------------------------*/

        ArrayList<Video> videoList = new ArrayList<>();

        //获取命中的数据
        SearchHits hits = searchResponse.getHits();

        SearchHit[] hitss = hits.getHits();

        //获取搜索的数据数组
        for (SearchHit doc : hitss) {

            //获取map数据
            Map<String, Object> sourceAsMap = doc.getSourceAsMap();

            //获取数据
            String id = sourceAsMap.get("id").toString();
            String title = sourceAsMap.get("title").toString();
            String description = sourceAsMap.get("description").toString();
            String videoPath = sourceAsMap.get("videoPath").toString();
            String coverPath = sourceAsMap.get("coverPath").toString();
            String status = sourceAsMap.get("status").toString();
            String categoryId = sourceAsMap.get("categoryId").toString();
            String userId = sourceAsMap.get("userId").toString();

            //判断该数据是否为空
            //boolean b = sourceAsMap.containsKey("groupId");

            /*String groupId =null;
            if(sourceAsMap.get("groupId")!=null){
                groupId = sourceAsMap.get("groupId").toString();
            }*/

            String groupId =sourceAsMap.get("groupId")!=null?sourceAsMap.get("groupId").toString():null;

            String createTimes = sourceAsMap.get("createTime").toString();
            Date createTime =null;
            try {
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                createTime = simpleDateFormat.parse(createTimes);
            } catch (ParseException e) {
                e.printStackTrace();
            }

            //将数据封装为对象
            Video video = new Video(id, title, description, videoPath, coverPath, status, createTime, categoryId, userId, groupId);


            /**处理高亮的数据*/
            Map<String, HighlightField> highlightFields = doc.getHighlightFields();

            if(highlightFields.get("title")!=null){
                String titles = highlightFields.get("title").fragments()[0].toString();
                video.setTitle(titles);
            }

            if(highlightFields.get("description")!=null){
                String descriptions = highlightFields.get("description").fragments()[0].toString();
                video.setDescription(descriptions);
            }

            //将封装的对象放入集合
            videoList.add(video);
        }
        return videoList;
    }
}


